//-------------------------------------------------------------------
//	Copyright (c) 2013-2014  Zhirnov Andrey
//	This file is part of the "UX OpwnGL Framework" project.
//	See copyright notice in "UX_GL_Framework.h".
//-------------------------------------------------------------------
/*
	OpenCL generator helper class.
*/

#pragma once

#include <Includes.h>

namespace Framework
{

	//
	// OpenCL Generator
	//

	struct UX_EXPORT CLGenerator
	{
	// types
	public:
		struct Texture
		{
			uint				index;	// argument number in kernel
			GLTexturePtr		tex;
			cl_memory::type		flags;
			///
			Texture () : index(-1) {}
			Texture (uint index, const GLTexturePtr &tex, cl_memory::type flags = cl_memory::WRITE_ONLY) :
				index(index), tex(tex), flags(flags) {}
		};

		struct MemImage
		{
			uint						index;	// argument number in kernel
			uni_array<uint8>			data;
			cl_img_channel_order::type	order;
			cl_img_channel::type		channel;
			cl_memory::type				flags;
			///
			MemImage () : index(-1)
			{}

			MemImage (uint index, const uni_array<uint8> &data, cl_img_channel_order::type order,
					  cl_img_channel::type channel, cl_memory::type flags = cl_memory::WRITE_ONLY) :
				index(index), data(data), flags(flags), order(order), channel(channel)
			{}
		};

		struct Image
		{
			uint			index;
			Ptr< CLImage >	image;
			///
			Image () : index(-1)
			{}

			Image (uint index, CLImage *climage) :
				index(index), image(climage)
			{}
		};

		struct Variant
		{
			uint			index;	// argument number in kernel
			const void *	ptr;
			uint			size;
			///
			Variant () : index(-1), ptr(null), size(0) {}
			
			template <typename T>
			Variant (uint index, T &value) : index(-1), ptr(&value), size(sizeof(value)) {}
		};

		typedef uni_array< Texture >	texture_args_t;
		typedef uni_array< Variant >	variant_args_t;
		typedef uni_array< MemImage >	memimage_args_t;
		typedef uni_array< Image >		image_args_t;


	// methods
	public:

		static bool Run (CLQueue &q, CLKernel &k,
						 const svec3 &offset, const svec3 &dim,
						 const texture_args_t &textures = texture_args_t(),
						 const memimage_args_t &images = memimage_args_t(),
						 const image_args_t &clImages = image_args_t());

		static bool Run (CLQueue &q, CLProgram &prog, uni_c_string kernelName,
						 const svec3 &offset, const svec3 &dim,
						 const texture_args_t &textures = texture_args_t(),
						 const memimage_args_t &images = memimage_args_t(),
						 const image_args_t &clImages = image_args_t(),
						 const variant_args_t &args = variant_args_t());
		
		static bool Run (uni_c_string programName, uni_c_string preprocessor, uni_c_string options,
						 uni_c_string kernelName, const svec3 &offset, const svec3 &dim,
						 const texture_args_t &textures = texture_args_t(),
						 const memimage_args_t &images = memimage_args_t(),
						 const image_args_t &clImages = image_args_t(),
						 const variant_args_t &args = variant_args_t());
	};


}	// Framework
